"""
   依赖项
"""
from fastapi import Header, Depends
from jose import jwt, JWTError
from starlette import status
from typing_extensions import Annotated

from conf.config import config
from db.redis_db import redis_pool
from service.user_service import UserService
from utils.constants import StatusCodeEnum, ROLE_PERMISSIONS
from utils.exceptions import CustomHTTPException


def check_access_token(access_token: str = Header()):
    """
    校验令牌是否有效
    :param access_token: 访问令牌
    """
    try:
        payload = jwt.decode(access_token, config['access_token']['SECRET_KEY'],
                             algorithms=[config['access_token']['ALGORITHM']])
        phone = payload.get("phone")
    except JWTError:
        raise CustomHTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            code=StatusCodeEnum.ACCESS_TOKEN_DECODE_ERR.code,
            msg=StatusCodeEnum.ACCESS_TOKEN_DECODE_ERR.errmsg
        )

    redis_conn = redis_pool.get_conn()
    access_token_key = f'access_token:{phone}'
    access_token_in_redis = redis_conn.get(access_token_key)

    if access_token_in_redis == access_token:
        return access_token
    else:
        raise CustomHTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            code=StatusCodeEnum.ACCESS_TOKEN_HAS_EXPIRED.code,
            msg=StatusCodeEnum.ACCESS_TOKEN_HAS_EXPIRED.errmsg
        )


def validate_phone(phone: str) -> str:
    """
    校验手机号
    :param phone: 手机号
    """
    phone = phone.strip()

    # 校验手机号长度
    if len(phone) != 11:
        raise CustomHTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            code=StatusCodeEnum.FORMAT_OF_PHONE_NUMBER_ERR.code,
            msg=StatusCodeEnum.FORMAT_OF_PHONE_NUMBER_ERR.errmsg
        )

    # 校验手机号开头
    if not phone.startswith('1'):
        raise CustomHTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            code=StatusCodeEnum.FORMAT_OF_PHONE_NUMBER_ERR.code,
            msg=StatusCodeEnum.FORMAT_OF_PHONE_NUMBER_ERR.errmsg
        )

    # 其他校验逻辑...

    return phone


def check_user_defined_article_rewrite_permissions(access_token: str = Header()):
    """
    校验用户自定义文章改写权限
    :param access_token: 访问令牌
    :return:
    """
    payload = jwt.decode(access_token, config['access_token']['SECRET_KEY'],
                         algorithms=[config['access_token']['ALGORITHM']])
    phone = payload.get("phone")
    user_server = UserService(phone=phone)
    user = user_server.get_user()
    role_id = user.get("role_id")
    if role_id in [ROLE_PERMISSIONS.get("operation"), ROLE_PERMISSIONS.get("merchant_operation"),
                   ROLE_PERMISSIONS.get("admin")]:
        pass
    else:
        raise CustomHTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            code=StatusCodeEnum.NO_PERMISSION_TO_ACCESS.code,
            msg=StatusCodeEnum.NO_PERMISSION_TO_ACCESS.errmsg
        )


def get_user_id(access_token: str = Header()):
    """
    获取用户id
    :param access_token: 访问令牌
    :return:
    """
    payload = jwt.decode(access_token, config['access_token']['SECRET_KEY'],
                         algorithms=[config['access_token']['ALGORITHM']])
    user_id = payload.get("user_id")
    return user_id


def select_user_token_left(user_id: Annotated[int, Depends(get_user_id)]):
    """
    查询用户剩余token
    :param user_id: 用户id
    :return:
    """
    # 查询用户token余量
    user_service = UserService()
    user_token_left = user_service.get_user_token_left(user_id=user_id)
    return user_token_left
